package com.sky.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        /**
         *1、StringBuilder 是用于高效操作字符串的可变对象类
         *   :链式调用：append() 方法返回 StringBuilder 对象本身
         *   :可变性：直接在原对象上修改，避免因字符串拼接产生大量临时 String 对象，性能优于 + 操作符。
         *   :线程安全性：StringBuilder 是非线程安全的，适用于单线程环境。
         *
         *2、StringBuffer 与 StringBuilder 功能相同，但所有方法用 synchronized 修饰，保证线程安全。
         *   :可变性：与 StringBuilder 相同。
         *   :链式调用：与 StringBuilder 相同。
         *   :线程安全性：StringBuffer 是线程安全的，但性能较差，适用于多线程环境。
         *
         *3、StringJoiner (Java 8+)
         *   :用于高效拼接字符串，支持指定分隔符和前缀后缀。
         *   :链式调用：add() 方法返回 StringJoiner 对象本身。
         *   :可变性：与 StringBuilder相同
         *   :线程安全性：非线程安全。
         */

        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}
